import {
  Alert,
  Button,
  Collapse,
  Form,
  Icon,
  Modal,
  Radio,
  Row,
  Spin,
  Table,
  Upload,
} from 'antd'
import React, { useMemo, useState } from 'react'
import { useDynamicList, useUpdateEffect } from 'ahooks'
import CatalogSelector from './components/CatalogSelector'
import ImportResultModal from './components/ImportResultModal'
import { SmallFormLayout } from '@/layouts/Form'
import request from '@/utils/request'
import useProcessCatalogTreeData from '@/hooks/UseProcessCatalogTreeData'
import useModal from '@/hooks/UseModal'

const { Panel } = Collapse

function dfs(data) {
  return data.map(each => ({
    value: each.title,
    label: each.title,
    children: dfs(each.children),
  }))
}

function ImportExportManager({ form, onCancel, ...rest }) {
  const { getFieldDecorator, getFieldValue, getFieldsValue, setFieldsValue } = form
  const [fileList, setFileList] = useState([])
  const { list, replace, resetList } = useDynamicList([])
  const [loading, setLoading] = useState(false)
  const { data, loading: catalogLoading } = useProcessCatalogTreeData(false)
  const options = useMemo(() => dfs(data), [data])
  const [activeKeys, setActiveKeys] = useState([])
  const hasErrorFile = list.some(item => item.data.some(e => e.importState !== 0))
  const { data: modalData, showModal, hideModal, visible } = useModal([])

  useUpdateEffect(() => {
    if (fileList.length > 0) {
      const formData = new FormData()
      fileList.forEach((file) => {
        formData.append('files', file)
      })
      formData.append('importType', getFieldValue('importType'))
      setFileList([])
      setLoading(true)
      request
        .post('/process/resolveImportFiles', {
          data: formData,
          requestType: 'form',
        })
        .then(({ json }) => {
          const data = JSON.parse(json)
          resetList(data)
          setActiveKeys(data.map(item => item.fileId))
        })
        .finally(() => {
          setLoading(false)
        })
    }
  }, [fileList])

  function onMountCatalogsChange(record, catalogNames) {
    const { configId, fileId } = record
    const fileIndex = list.findIndex(file => file.fileId === fileId)
    const file = list[fileIndex]
    replace(fileIndex, {
      ...file,
      data: file.data.map(config =>
        config.configId === configId
          ? {
              ...config,
              mountCatalogs: catalogNames.slice(),
            }
          : config,
      ),
    })
  }

  const columns = [
    {
      dataIndex: 'processName',
      title: '流程名称',
      width: '28%',
    },
    {
      dataIndex: 'processCode',
      title: '流程编码',
      width: '28%',
    },
    {
      dataIndex: 'versionNumber',
      title: '版本号',
      width: '7%',
    },
    {
      dataIndex: 'importState',
      title: '导入状态',
      render: (state, record) => (
        <span className={state === 0 ? 'text-success' : 'text-danger'}>{record.importMessage}</span>
      ),
      width: '15%',
    },
    {
      dataIndex: 'mountCatalogs',
      title: '挂载目录',
      width: '22%',
      align: 'center',
      render: (mountCatalogs, record) => (
        <CatalogSelector
          value={mountCatalogs}
          onChange={catalogNames => onMountCatalogsChange(record, catalogNames)}
          options={options}
          placeholder="--请选择--"
        />
      ),
    },
  ]

  function renderHeader(item) {
    const hasError = item.data.some(e => e.importState !== 0)
    return (
      <span className={hasError ? 'text-danger' : 'text-success'}>
        <Icon className="margin-right" type="file" />
        {item.filename}
      </span>
    )
  }

  const closeModal = () => {
    setFileList([])
    resetList([])
    onCancel()
  }

  const handleConfirm = () => {
    setLoading(true)
    request
      .post('/process/importResolvedFiles', {
        data: { json: JSON.stringify(list), ...getFieldsValue() },
      })
      .then(result => showModal(result))
      .finally(() => setLoading(false))
  }

  const fromSertransTemplate = getFieldValue('importType') === 'FromSertransTemplate'

  const props = {
    onRemove: (file) => {
      setFileList((prev) => {
        const index = prev.indexOf(file)
        const newFileList = prev.slice()
        newFileList.splice(index, 1)
        return newFileList
      })
    },
    beforeUpload: (file) => {
      setFileList(prev => [...prev, file])
      return false
    },
    fileList,
    multiple: !fromSertransTemplate,
    showUploadList: false,
    accept: '.zip',
  }

  const handleImportTypeChange = (e) => {
    const { value } = e.target
    if (value === 'FromSertransTemplate') {
      setFieldsValue({
        versionEffectType: 'Manually',
      })
    }
    else if (value === 'FromExportedFile') {
      setFieldsValue({
        versionEffectType: 'Immediately',
      })
    }
  }

  return (
    <Modal
      maskClosable={!loading}
      title="导入流程配置"
      destroyOnClose
      onCancel={closeModal}
      onOk={handleConfirm}
      okText="确认导入"
      okButtonProps={{
        disabled: list.length === 0 || hasErrorFile,
        loading,
      }}
      {...rest}
    >
      <Spin spinning={loading || catalogLoading}>
        <Form className="margin-bottom" {...SmallFormLayout}>
          <Row>
            <Form.Item label="导入方式">
              {getFieldDecorator('importType', {
                initialValue: 'FromExportedFile',
              })(
                <Radio.Group onChange={handleImportTypeChange}>
                  <Radio value="FromExportedFile">ZIP导出文件</Radio>
                  {/* <Radio value="FromSertransTemplate">从Sertrans模板配置导入</Radio> */}
                </Radio.Group>,
              )}
            </Form.Item>
          </Row>
          <Row>
            <Form.Item label="导入文件格式">
              {getFieldDecorator('importFileType', {
                initialValue: 'Zip',
              })(
                <Radio.Group>
                  <Radio value="Zip">.zip</Radio>
                </Radio.Group>,
              )}
            </Form.Item>
          </Row>
          <Row>
            <Form.Item label="版本生效方式">
              {getFieldDecorator('versionEffectType', {
                initialValue: 'Immediately',
              })(
                <Radio.Group>
                  <Radio value="Immediately">立即生效</Radio>
                  <Radio value="Manually">手动生效</Radio>
                </Radio.Group>,
              )}
            </Form.Item>
          </Row>
          <Row style={{ display: fromSertransTemplate ? 'none' : '' }}>
            <Form.Item
              label="配置覆盖方式"
              extra={
                getFieldValue('overwriteType') === 'Full'
                  ? '所有字段以导出的配置为准，全部覆盖'
                  : '部分字段将不会覆盖原有的配置，如：HTTP调用的请求地址、超时时间、是否开启Mock、日志写入策略等'
              }
            >
              {getFieldDecorator('overwriteType', {
                initialValue: 'IgnoreSensitiveFields',
              })(
                <Radio.Group>
                  <Radio value="IgnoreSensitiveFields">敏感字段不覆盖</Radio>
                  <Radio value="Full">完全覆盖</Radio>
                </Radio.Group>,
              )}
            </Form.Item>
          </Row>

          <Row style={{ display: fromSertransTemplate ? 'none' : '' }}>
            <Form.Item
              label="HTTP Mock 覆盖方式"
              extra={
                getFieldValue('httpMockOverwriteType') === 'AllOpenMock'
                  ? '所有HTTP调用环节在导入后都会自动开启mock'
                  : (getFieldValue('httpMockOverwriteType') === 'AllCloseMock'
                      ? '所有HTTP调用环节在导入后都会自动关闭mock'
                      : undefined)
              }
            >
              {getFieldDecorator('httpMockOverwriteType', {
                initialValue: 'Default',
              })(
                <Radio.Group>
                  <Radio value="Default">默认</Radio>
                  <Radio value="AllCloseMock">全部关闭mock</Radio>
                  <Radio value="AllOpenMock">全部开启mock</Radio>
                </Radio.Group>,
              )}
            </Form.Item>
          </Row>

          <Row>
            <Form.Item
              label="导入文件"
              extra={fromSertransTemplate ? null : '支持多个ZIP文件同时上传'}
            >
              {getFieldDecorator('importFiles')(
                <Upload {...props}>
                  <Button type="primary" icon="upload">
                    上传文件
                  </Button>
                </Upload>,
              )}
            </Form.Item>
          </Row>

          {fromSertransTemplate && (
            <Alert
              style={{ marginLeft: '60px', marginTop: '8px' }}
              message="注意：从Sertrans导出的配置文件，有且只能导入一次，不可重复导入！"
              type="warning"
              showIcon
            />
          )}
        </Form>
        {list.length > 0 && (
          <>
            <div className="ant-detail-title">导入文件内容</div>
            <Collapse onChange={setActiveKeys} activeKey={activeKeys} expandIconPosition="right">
              {list.map(item => (
                <Panel header={renderHeader(item)} key={item.fileId}>
                  <Table
                    rowKey="configId"
                    bordered
                    columns={columns}
                    dataSource={item.data}
                    pagination={false}
                  />
                </Panel>
              ))}
            </Collapse>
          </>
        )}
      </Spin>
      <ImportResultModal
        visible={visible}
        data={modalData}
        closeSelf={hideModal}
        closeParent={closeModal}
      />
    </Modal>
  )
}

export default Form.create()(ImportExportManager)
